package com.junqson.je.content.service;

import com.aliyun.oss.*;
import com.junqson.je.common.UserHolder;
import com.junqson.je.common.model.ApiResult;
import com.junqson.je.content.model.FileModel;
import com.junqson.je.content.repo.FileRepo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.UUID;

/**
 * @Descriptions
 * @Company
 * @Author Junqson
 * @Date 2020/2/2 22:43
 * @Version 1.0
 */
@Service
@Slf4j
public class FileService {
    /**
     * 以下的敏感信息必须通过配置文件注入，避免暴露
     * <p>
     * OSS服务器节点，此处指定为外网访问节点，上线后改为内网ECS节点
     */
    private static String endpoint = "oss-cn-beijing.aliyuncs.com";

    @Value("${oss.access-key-id}")
    private String accessKeyId;

    @Value("${oss.access-secret}")
    private String accessKeySecret;

    private static String fileUrlDomain = "";

    private static String bucketName = "";

    /**
     * 允许的图片后缀
     */
    public static final String[] imgAllowed = {"BMP", "GIF", "JPG", "JPEG", "PNG"};

    /**
     * 允许的文档后缀
     */
    public static final String[] docAllowed = {"doc", "docx", "pdf", "xls", "xlsx", "ppt", "txt", "zip", "rar", "gz","mp3","mp4"};

    @Autowired
    FileRepo fileRepo;

    public ApiResult upload(MultipartFile file) {
        if (file == null) {
            return ApiResult.error("文件不能为null");
        }


        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // OSS client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 如果是文档，要考虑按照文档原有的文件名上传，但是要保证文件名不可重复
            String originalFilename = file.getOriginalFilename();
            int dotPos = originalFilename.lastIndexOf(".");
            if (dotPos <= 0) {
                return ApiResult.error("非法文件");
            }
            String extName = originalFilename.substring(dotPos + 1);

            if (!isImg(extName) && !isDoc(extName)) {
                return ApiResult.error("不支持的文件格式");
            }

            /**
             * 获取文件名和字节流,执行上传逻辑
             */
            String filename = originalFilename.substring(0, dotPos) + UUID.randomUUID().toString().replace("-", "")
                    .substring(0, 5) + "." + extName;

            client.putObject(bucketName, filename, file.getInputStream());

            String fileUrl = fileUrlDomain + "/" + filename;
            int userId = UserHolder.get().getUserId();
            log.info("user id = {}, upload {}, extName {}, to url {}, size {}", userId, originalFilename, extName, fileUrl, file.getSize());

            FileModel fileModel = new FileModel();
            fileModel.setUserId(UserHolder.get().getUserId());
            fileModel.setUploadTime(new Date());
            fileModel.setFileName(originalFilename);
            fileModel.setExtName(extName);
            fileModel.setFileUrl(fileUrl);
            fileModel.setSize(file.getSize());

            fileRepo.save(fileModel);
            return ApiResult.success(fileModel);

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message: " + oe.getErrorCode());
            System.out.println("Error Code:       " + oe.getErrorCode());
            System.out.println("Request ID:      " + oe.getRequestId());
            System.out.println("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ce.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            client.shutdown();
        }
        return ApiResult.error("上传失败");
    }
    /**
     * 是否是支持的文档
     * @return
     */
    public boolean isDoc(String extName) {
        for (String ext : docAllowed) {
            if (ext.equalsIgnoreCase(extName)) {
                return true;
            }
        }
        return false;

    }

    /**
     * 是否是支持的图片格式
     * @return
     */
    public boolean isImg(String extName) {
        for (String ext : imgAllowed) {
            if (ext.equalsIgnoreCase(extName)) {
                return true;
            }
        }
        return false;
    }

//    /**
//     * 测试类
//     * @param args
//     */
//    public static void main(String[] args) {
//
//        OSS client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//
//        try {
//            String name = "test" + UUID.randomUUID().toString().substring(0, 3) + ".txt";
//            String content = "sddsadsad";
//
//            client.putObject(bucketName, name, new ByteArrayInputStream(content.getBytes()));
//
//        } catch (OSSException oe) {
//            oe.printStackTrace();
//
//        } catch (ClientException ce) {
//            ce.printStackTrace();
//        } finally {
//            client.shutdown();
//        }
//
//    }


}
